package com.datagateway.controller;

import com.datagateway.component.LoadBalancerManager;
import com.datagateway.component.ServiceDiscoveryManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
 * 负载均衡控制器
 * 提供负载均衡和服务发现相关的REST API接口
 * 
 * @author Data Gateway Team
 * @version 1.0.0
 */
@RestController
@RequestMapping("/data-gateway/api/load-balancer")
public class LoadBalancerController {

    @Autowired
    private LoadBalancerManager loadBalancerManager;

    @Autowired
    private ServiceDiscoveryManager serviceDiscoveryManager;

    /**
     * 获取负载均衡状态
     * 
     * @return 负载均衡状态信息
     */
    @GetMapping("/status")
    public Map<String, Object> getLoadBalancerStatus() {
        Map<String, Object> status = new HashMap<>();
        
        try {
            // 获取负载均衡统计信息
            LoadBalancerManager.LoadBalancingStatistics lbStats = loadBalancerManager.getStatistics();
            status.put("loadBalancer", lbStats);
            
            // 获取服务发现统计信息
            ServiceDiscoveryManager.ServiceDiscoveryStatistics sdStats = serviceDiscoveryManager.getStatistics();
            status.put("serviceDiscovery", sdStats);
            
            // 获取所有服务实例状态
            List<LoadBalancerManager.ServiceInstance> instances = loadBalancerManager.getAllInstanceStatus();
            status.put("instances", instances);
            
            // 获取所有服务信息
            List<ServiceDiscoveryManager.ServiceInfo> services = serviceDiscoveryManager.getAllServices();
            status.put("services", services);
            
            status.put("status", "UP");
            status.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            status.put("status", "DOWN");
            status.put("error", e.getMessage());
            status.put("timestamp", System.currentTimeMillis());
        }
        
        return status;
    }

    /**
     * 添加服务实例
     * 
     * @param request 添加实例请求
     * @return 操作结果
     */
    @PostMapping("/instances")
    public Map<String, Object> addServiceInstance(@RequestBody Map<String, Object> request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            String instanceId = (String) request.get("instanceId");
            String host = (String) request.get("host");
            Integer port = (Integer) request.get("port");
            Integer weight = (Integer) request.getOrDefault("weight", 1);
            
            if (instanceId == null || host == null || port == null) {
                result.put("success", false);
                result.put("message", "缺少必要参数: instanceId, host, port");
                return result;
            }
            
            boolean success = loadBalancerManager.addServiceInstance(instanceId, host, port, weight);
            
            result.put("success", success);
            result.put("message", success ? "服务实例添加成功" : "服务实例添加失败");
            result.put("instanceId", instanceId);
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "添加服务实例异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 移除服务实例
     * 
     * @param instanceId 实例ID
     * @return 操作结果
     */
    @DeleteMapping("/instances/{instanceId}")
    public Map<String, Object> removeServiceInstance(@PathVariable String instanceId) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            boolean success = loadBalancerManager.removeServiceInstance(instanceId);
            
            result.put("success", success);
            result.put("message", success ? "服务实例移除成功" : "服务实例移除失败");
            result.put("instanceId", instanceId);
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "移除服务实例异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 获取服务实例状态
     * 
     * @param instanceId 实例ID
     * @return 实例状态
     */
    @GetMapping("/instances/{instanceId}")
    public Map<String, Object> getInstanceStatus(@PathVariable String instanceId) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            LoadBalancerManager.ServiceInstance instance = loadBalancerManager.getInstanceStatus(instanceId);
            
            if (instance != null) {
                result.put("success", true);
                result.put("instance", instance);
            } else {
                result.put("success", false);
                result.put("message", "服务实例不存在");
            }
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取实例状态异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 获取所有服务实例状态
     * 
     * @return 实例状态列表
     */
    @GetMapping("/instances")
    public Map<String, Object> getAllInstanceStatus() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            List<LoadBalancerManager.ServiceInstance> instances = loadBalancerManager.getAllInstanceStatus();
            
            result.put("success", true);
            result.put("instances", instances);
            result.put("count", instances.size());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取实例状态异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 获取健康的服务实例
     * 
     * @return 健康实例列表
     */
    @GetMapping("/instances/healthy")
    public Map<String, Object> getHealthyInstances() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            List<LoadBalancerManager.ServiceInstance> instances = loadBalancerManager.getHealthyInstances();
            
            result.put("success", true);
            result.put("instances", instances);
            result.put("count", instances.size());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取健康实例异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 设置负载均衡策略
     * 
     * @param request 策略设置请求
     * @return 操作结果
     */
    @PostMapping("/strategy")
    public Map<String, Object> setLoadBalancingStrategy(@RequestBody Map<String, Object> request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            String strategy = (String) request.get("strategy");
            
            if (strategy == null) {
                result.put("success", false);
                result.put("message", "缺少必要参数: strategy");
                return result;
            }
            
            boolean success = loadBalancerManager.setLoadBalancingStrategy(strategy);
            
            result.put("success", success);
            result.put("message", success ? "负载均衡策略设置成功" : "负载均衡策略设置失败");
            result.put("strategy", strategy);
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "设置负载均衡策略异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 分发测试请求
     * 
     * @param request 测试请求
     * @return 请求结果
     */
    @PostMapping("/test-request")
    public Map<String, Object> testRequest(@RequestBody Map<String, Object> request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            Object testData = request.getOrDefault("data", "test request");
            
            CompletableFuture<LoadBalancerManager.RequestResult> future = 
                loadBalancerManager.distributeRequest(testData);
            
            LoadBalancerManager.RequestResult requestResult = future.get();
            
            result.put("success", true);
            result.put("requestResult", requestResult);
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "测试请求异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 注册服务
     * 
     * @param request 服务注册请求
     * @return 操作结果
     */
    @PostMapping("/services")
    public Map<String, Object> registerService(@RequestBody Map<String, Object> request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            String serviceId = (String) request.get("serviceId");
            String serviceName = (String) request.get("serviceName");
            String host = (String) request.get("host");
            Integer port = (Integer) request.get("port");
            Integer weight = (Integer) request.getOrDefault("weight", 1);
            
            if (serviceId == null || serviceName == null || host == null || port == null) {
                result.put("success", false);
                result.put("message", "缺少必要参数: serviceId, serviceName, host, port");
                return result;
            }
            
            ServiceDiscoveryManager.ServiceInfo serviceInfo = new ServiceDiscoveryManager.ServiceInfo(
                serviceId, serviceName, host, port, weight
            );
            
            boolean success = serviceDiscoveryManager.registerService(serviceInfo);
            
            result.put("success", success);
            result.put("message", success ? "服务注册成功" : "服务注册失败");
            result.put("serviceId", serviceId);
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "服务注册异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 注销服务
     * 
     * @param serviceId 服务ID
     * @return 操作结果
     */
    @DeleteMapping("/services/{serviceId}")
    public Map<String, Object> deregisterService(@PathVariable String serviceId) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            boolean success = serviceDiscoveryManager.deregisterService(serviceId);
            
            result.put("success", success);
            result.put("message", success ? "服务注销成功" : "服务注销失败");
            result.put("serviceId", serviceId);
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "服务注销异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 发现服务
     * 
     * @param serviceName 服务名称
     * @return 服务列表
     */
    @GetMapping("/services/discover/{serviceName}")
    public Map<String, Object> discoverServices(@PathVariable String serviceName) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            List<ServiceDiscoveryManager.ServiceInfo> services = 
                serviceDiscoveryManager.discoverServices(serviceName);
            
            result.put("success", true);
            result.put("services", services);
            result.put("count", services.size());
            result.put("serviceName", serviceName);
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "服务发现异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 获取服务信息
     * 
     * @param serviceId 服务ID
     * @return 服务信息
     */
    @GetMapping("/services/{serviceId}")
    public Map<String, Object> getServiceInfo(@PathVariable String serviceId) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            ServiceDiscoveryManager.ServiceInfo serviceInfo = 
                serviceDiscoveryManager.getServiceInfo(serviceId);
            
            if (serviceInfo != null) {
                result.put("success", true);
                result.put("service", serviceInfo);
            } else {
                result.put("success", false);
                result.put("message", "服务不存在");
            }
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取服务信息异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 获取所有服务信息
     * 
     * @return 服务信息列表
     */
    @GetMapping("/services")
    public Map<String, Object> getAllServices() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            List<ServiceDiscoveryManager.ServiceInfo> services = 
                serviceDiscoveryManager.getAllServices();
            
            result.put("success", true);
            result.put("services", services);
            result.put("count", services.size());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取服务信息异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 获取服务组信息
     * 
     * @param serviceName 服务名称
     * @return 服务组信息
     */
    @GetMapping("/services/groups/{serviceName}")
    public Map<String, Object> getServiceGroup(@PathVariable String serviceName) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            ServiceDiscoveryManager.ServiceGroup serviceGroup = 
                serviceDiscoveryManager.getServiceGroup(serviceName);
            
            result.put("success", true);
            result.put("serviceGroup", serviceGroup);
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取服务组信息异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 发送心跳
     * 
     * @param serviceId 服务ID
     * @return 操作结果
     */
    @PostMapping("/services/{serviceId}/heartbeat")
    public Map<String, Object> sendHeartbeat(@PathVariable String serviceId) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            boolean success = serviceDiscoveryManager.sendHeartbeat(serviceId);
            
            result.put("success", success);
            result.put("message", success ? "心跳发送成功" : "心跳发送失败");
            result.put("serviceId", serviceId);
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "发送心跳异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 获取服务健康状态
     * 
     * @param serviceId 服务ID
     * @return 健康状态
     */
    @GetMapping("/services/{serviceId}/health")
    public Map<String, Object> getServiceHealth(@PathVariable String serviceId) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            ServiceDiscoveryManager.ServiceHealth health = 
                serviceDiscoveryManager.getServiceHealth(serviceId);
            
            if (health != null) {
                result.put("success", true);
                result.put("health", health);
            } else {
                result.put("success", false);
                result.put("message", "服务健康状态不存在");
            }
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取服务健康状态异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 获取所有服务健康状态
     * 
     * @return 健康状态列表
     */
    @GetMapping("/services/health")
    public Map<String, Object> getAllServiceHealth() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            List<ServiceDiscoveryManager.ServiceHealth> healthList = 
                serviceDiscoveryManager.getAllServiceHealth();
            
            result.put("success", true);
            result.put("healthList", healthList);
            result.put("count", healthList.size());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取服务健康状态异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 设置负载均衡配置
     * 
     * @param request 配置请求
     * @return 操作结果
     */
    @PostMapping("/config")
    public Map<String, Object> setLoadBalancerConfig(@RequestBody Map<String, Object> request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            Boolean enabled = (Boolean) request.get("enabled");
            String strategy = (String) request.get("strategy");
            Integer healthCheckInterval = (Integer) request.get("healthCheckInterval");
            Integer maxRetries = (Integer) request.get("maxRetries");
            Integer connectionTimeout = (Integer) request.get("connectionTimeout");
            Integer readTimeout = (Integer) request.get("readTimeout");
            
            if (enabled == null || strategy == null || healthCheckInterval == null || 
                maxRetries == null || connectionTimeout == null || readTimeout == null) {
                result.put("success", false);
                result.put("message", "缺少必要参数");
                return result;
            }
            
            loadBalancerManager.setLoadBalancingConfig(enabled, strategy, healthCheckInterval, 
                maxRetries, connectionTimeout, readTimeout);
            
            result.put("success", true);
            result.put("message", "负载均衡配置设置成功");
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "设置负载均衡配置异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 设置服务发现配置
     * 
     * @param request 配置请求
     * @return 操作结果
     */
    @PostMapping("/service-discovery/config")
    public Map<String, Object> setServiceDiscoveryConfig(@RequestBody Map<String, Object> request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            Boolean enabled = (Boolean) request.get("enabled");
            Integer registrationTimeout = (Integer) request.get("registrationTimeout");
            Integer heartbeatInterval = (Integer) request.get("heartbeatInterval");
            Integer expirationTime = (Integer) request.get("expirationTime");
            Integer cacheTimeout = (Integer) request.get("cacheTimeout");
            
            if (enabled == null || registrationTimeout == null || heartbeatInterval == null || 
                expirationTime == null || cacheTimeout == null) {
                result.put("success", false);
                result.put("message", "缺少必要参数");
                return result;
            }
            
            serviceDiscoveryManager.setServiceDiscoveryConfig(enabled, registrationTimeout, 
                heartbeatInterval, expirationTime, cacheTimeout);
            
            result.put("success", true);
            result.put("message", "服务发现配置设置成功");
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "设置服务发现配置异常: " + e.getMessage());
        }
        
        return result;
    }
}
